import { useEffect, useState } from "react";

// export const isFalsy = (value: unknown) => (value === 0 ? false : !value);
// 解决会删除有意义的false的问题，例如 {checked: false}
export const isVoid = (value: unknown) =>
  value === undefined || value === null || value === "";

/*
 * 清理对象的空值
 */
// export const cleanObject = (object: object) => {
// let a: object;
// a = {name: 'sss'}
// a = () => {}
// 以上情况下a是不会报错的，所以TS会反回一个空对象

// let a: { [key: string]: unknown };
// a = {name: 'sss'}
// a = () => {}
// 以上情况下a会报错
export const cleanObject = (object: { [key: string]: unknown }) => {
  // 在一个函数里，改变传入对象的本身是不好的
  const result = { ...object };
  Object.keys(result).forEach((key) => {
    const value = result[key];
    if (isVoid(value)) {
      delete result[key];
    }
  });
  return result;
};

// 抽离的useEffect逻辑
export const useMount = (callback: () => void) => {
  useEffect(() => {
    callback();
    // TODO 依赖项里加上callback会造成无限循环，这与useCallback以及useMemo有关
  }, []); // eslint-disable-line react-hooks/exhaustive-deps
};

// 处理快速事件
// const debunce = (func, delay) => {
//   let timer;
//   return () => {
//     if(timer) {
//       clearTimeout(timer)
//     }
//     timer = setTimeout(() => {
//       func()
//     }, delay)
//   }
// }
// const log = debunce(() => console.log("call"), 5000)
// log()
// log()
// log()

/**
 * debounce原理解析
 * 0s --------> 1s --------> 2s --------> ...
 * 注意：以上三个 log() 都是同步操作，所以都是在 0～1s这个时间段完成的
 * log()#1 ---> timeout#1
 * log()#2 ---> 发现-timeout#1，取消之。然后设置-timeout#2
 * log()#3 ---> 发现-timeout#2，取消之。然后设置-timeout#3
 *              log()#3执行结束，只剩timeout#3在等待
 */

// 后续使用泛型来规范返回值类型
// export const useDebounce = (value: unknown, delay?: number): any => {
//   const [debounceValue, setDebounceVale] = useState(value);
//
//   useEffect(() => {
//     // 每次value变化之后开启一个定时器
//     const timer = setTimeout(() => setDebounceVale(value), delay);
//     // 每次在上一个useEffect处理完以后再运行
//     return () => clearTimeout(timer);
//   }, [value, delay]);
//
//   return debounceValue;
// };

// 使用泛型来规范返回值类型
export const useDebounce = <V>(value: V, delay?: number) => {
  const [debounceValue, setDebounceVale] = useState(value);

  useEffect(() => {
    // 每次value变化之后开启一个定时器
    const timer = setTimeout(() => setDebounceVale(value), delay);
    // 每次在上一个useEffect处理完以后再运行
    return () => clearTimeout(timer);
  }, [value, delay]);

  return debounceValue;
};

/**
 * 作业：实现useArray
 */
export const useArray = <T>(initialArray: T[]) => {
  const [value, setValue] = useState(initialArray);
  const clear = () => {
    return setValue([]);
  };

  const removeIndex = (index: number) => {
    const copyValue = [...value];
    copyValue.splice(index, 1);
    return setValue(copyValue);
  };

  const add = (data: T) => {
    return setValue([...value, data]);
  };
  return {
    value,
    clear,
    removeIndex,
    add,
  };
};
